package com.jack.design_patterns.creational.prototype;

/**
 * 原型模式：是用于创建重复的对象，同时又能保证性能
 * 1.JackMyBatis：操作数据库，从数据库里面查询出很多记录(70%改变很少)
 * 2.每次查询数据库，查到以后把所有数据都封装成一个对象，返回
 * 10000 thread查询一个记录：new User("张三", 18); 每次创建一个对象封装并返回
 * 系统里面就会有10000个User;浪费内存
 * 3.解决：缓存，查过的保存
 * 如果再查相同的记录，拿到原来的原型对象
 * 4.此时直接拿到缓存中的对象
 */
public class MainTest {

    public static void main(String[] args) throws Exception {
        test3();
    }

    private static void test3() throws Exception {
        JackMybatis mybatis = new JackMybatis();
        // 得到的是从数据库中获取的原数据
        User user1 = mybatis.getUserFromCacheWithClone("jack");
        System.out.println("1-->" + user1);
        // 如果用户1拿到了user对象，然后做了修改，这里修改的是原数据并不会对缓存中的数据做修改
        // 因为第一次从数据库查询到的user对象克隆了一份放入了缓存中
        user1.setUsername("李四");
        System.out.println("1修改之后的数据-->" + user1);

        // 从缓存中的是原数据的克隆体
        // 然后在从缓存中得到原数据的克隆体之后，再做了一次克隆，才把数据返回来
        User user2 = mybatis.getUserFromCacheWithClone("jack");
        System.out.println("2-->" + user2);
        // 得到的是克隆体
        User user3 = mybatis.getUserFromCacheWithClone("jack");
        System.out.println("3-->" + user3);
        // 得到的是克隆体
        User user4 = mybatis.getUserFromCacheWithClone("jack");
        System.out.println("4-->" + user4);

        System.out.println("user1==user2:" + (user1 == user2));// false
    }

    private static void test2() throws Exception {
        JackMybatis mybatis = new JackMybatis();
        // 从缓存中直接拿数据，会十分危险
        User user1 = mybatis.getUserFromCache("jack");
        System.out.println("1-->" + user1);
        // 如果用户1拿到了user对象，然后做了修改
        user1.setUsername("李四");
        System.out.println("1修改之后的数据-->" + user1);

        // 用户2来拿，原本希望拿到的是user为张三的数据，实际上拿到的是user为李四的数据，这里就有问题
        User user2 = mybatis.getUserFromCache("jack");
        System.out.println("2-->" + user2);
        User user3 = mybatis.getUserFromCache("jack");
        System.out.println("3-->" + user3);
        User user4 = mybatis.getUserFromCache("jack");
        System.out.println("4-->" + user4);

        System.out.println("user1==user2:" + (user1 == user2));// true
    }

    private static void test1() {
        JackMybatis mybatis = new JackMybatis();
        User user1 = mybatis.getUser("jack");
        User user2 = mybatis.getUser("jack");
        User user3 = mybatis.getUser("jack");
        User user4 = mybatis.getUser("jack");
    }

}
